package com.mo.security.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mo.entity.User;
import com.mo.mapper.UserMapper;
import com.mo.security.entity.LoginUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 在这里加载用户信息（从数据库中查找）
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Resource
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, username);
        User user = userMapper.selectOne(wrapper);
        if (Objects.isNull(user)) {
            throw new RuntimeException("用户不存在");
        }

        /*
          模拟的权限列表，需要从数据库中查询得到，类型是 String[]
          如果是以 ROLE_ 开头，SpringSecurity 会把他当成是角色，注意是严格区分大小写
          一般是使用 SimpleGrantedAuthority 来创建角色和权限
          角色：
          SimpleGrantedAuthority roleUser = new SimpleGrantedAuthority("ROLE_USER");
          SimpleGrantedAuthority roleAdmin = new SimpleGrantedAuthority("ROLE_ADMIN");

          权限：
          SimpleGrantedAuthority readPrivilege = new SimpleGrantedAuthority("READ_PRIVILEGE");
          SimpleGrantedAuthority writePrivilege = new SimpleGrantedAuthority("WRITE_PRIVILEGE");

          构建一个权限列表，示例如下:
         */
        String[] auths = new String[]{"sys:add", "sys:edit", "sys:delete", "ROLE_ADMIN"};
        List<GrantedAuthority> authorityList = AuthorityUtils.createAuthorityList(auths);
        user.setAuthorities(authorityList);

        return new LoginUser(user, authorityList);
    }
}